﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using JetBrains.Annotations;
using UnityEngine;
public partial class CyberU
{
    
    public static int LoopedIndex(int n, int index)
    {
        if (index == 0)
        {
            return index;
        }

        while (index < 0)
            index += n;
        index %= n;
        return index;
    }
    public static IEnumerator RunCoroutine(System.Action action)
    {
        yield return null;
        action();
    }
    public delegate void Action();
    public delegate void Action<in T>(T arg);
    public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
    public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
    
    public sealed class AutoIndexList<T> : IList<T>
    {
        private readonly List<T> _list = new List<T>();
        public T Pop(int index)
        {
            if (_list.Count == 0)
                throw new InvalidOperationException("无法弹出元素，列表为空。");
            T lastItem = _list[index];
            _list.RemoveAt(index);
            return lastItem;
        }
        public T this[int index]
        {
            get
            {
                if (_list.Count == 0)
                    throw new InvalidOperationException("CircularList 不能为空，无法访问元素。");
                return _list[WrapIndex(index)];
            }
            set
            {
                if (_list.Count == 0)
                    throw new InvalidOperationException("CircularList 不能为空，无法修改元素。");
                _list[WrapIndex(index)] = value;
            }
        }

        private int WrapIndex(int index)
        {
            int count = _list.Count;
            if (count == 0) throw new InvalidOperationException();
            if (count == 1) return 0; // 避免不必要的模运算
            return (index % count + count) % count; // 处理负数和超范围索引
        }

        public int Count => _list.Count;
        public bool IsReadOnly => false;
        public void Add(T item) => _list.Add(item);
        public void Clear() => _list.Clear();
        public bool Contains(T item) => _list.Contains(item);
        public void CopyTo(T[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
        public IEnumerator<T> GetEnumerator() => _list.GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
        public int IndexOf(T item) => _list.IndexOf(item);
        public void Insert(int index, T item) => _list.Insert(WrapIndex(index), item);
        public bool Remove(T item) => _list.Remove(item);
        public void RemoveAt(int index) => _list.RemoveAt(WrapIndex(index));
    }

    public static bool Used([CanBeNull] object _ = null)
    {
        return !(_ is null);
    }

    public static bool Enabled([CanBeNull] object _ = null)
    {
        return !(_ is null)&& !(new Vector3().Equals(_));
    }


    public static void Announce()
    {
        Debug.Log("latest code alert here.");
    }
    public static void WarnLog(object obj)
    {
        Debug.LogWarning(obj);
    }
    public static void RunLog(object obj)
    {
        Debug.Log(obj);
    }
    public static void CheckIsNull(string name, object obj)
    {
        Debug.Log($"{name} is null: {obj is null}");
    }

    public static IEnumerable<(TFirst, TSecond)> Zip<TFirst, TSecond>(IEnumerable<TFirst> first, IEnumerable<TSecond> second)
    {
        using (IEnumerator<TFirst> e1 = first.GetEnumerator())
        using (IEnumerator<TSecond> e2 = second.GetEnumerator())
        {
            while (e1.MoveNext() && e2.MoveNext())
            {
                yield return (e1.Current, e2.Current);
            }
        }
    }

    public static void MustUsed(object obj)
    {
        if (obj == null)
        {
            ErrorLog("should not be  null:" + obj);
        }
    }

    public static class stupid
    {
        public static class Debug
        {
            public static bool EnableLog = true;
            public static bool EnableWarning = true;
            public static bool EnableError = true;

            public static void Error(object message)
            {
                if (EnableError) UnityEngine.Debug.LogError(FormatMessage("[ERROR] ", message));
            }

            public static void Warning(object message)
            {
                if (EnableWarning) UnityEngine.Debug.LogWarning(FormatMessage("[WARN] ", message));
            }

            public static void Log(object message)
            {
                if (message is Color color)
                {
                    print($"<color=#{ColorUtility.ToHtmlStringRGB(color)}></color>");
                    return;
                }
                if (EnableLog) print(message);
            }

            public static string FormatMessage(string prefix, object message)
            {
                return $"{prefix}[CyberU] {message}";
            }
        }
    }

    public static string GetType(object obj)
    {
        if (obj == null)
        {
            Debug.Log("null");
            return "null";
        }

        string typeName = obj.GetType().ToString();
        // Debug.Log(typeName);
        return typeName;
    }

}